#include<iostream>
#include<string>
#include<any>
#include<cassert>

class Any{
    private:
    class placeholder{
        public:
        virtual ~placeholder() {}
        virtual const std::type_info& type()=0;
        virtual placeholder* clone()=0;
    };
    template<class T>
    class holder:public placeholder{
        public:
        T _data;
        public:
        holder(const T& data):_data(data) {}
        ~holder() {}
        const std::type_info& type(){
            return typeid(T);
        }
        placeholder* clone(){
            return new holder(_data);
        }
    };
    placeholder* _content;
    public:
    template<class T>
    Any(const T& val):_content(new holder<T>(val)) {}
    Any(const Any& other){
        _content=other._content->clone();
    }
    ~Any(){
        if(_content) delete _content;
    }
    const std::type_info& type(){
        return (_content!=nullptr)?_content->type():typeid(void);
    }
    Any& swap(Any& other){
        std::swap(_content,other._content);
        return *this;
    }

    template<class T>
    Any operator=(const T& val){
        Any(val).swap(*this);
        return *this;
    }
    Any operator=(Any other){
        other.swap(*this);
        return *this;
    }
    template<class T>
    T* get(){
        assert(typeid(T)==_content->type());
        return &((holder<T>*)_content)->_data;
    }
};

class Test{
    private:
    std::string _data;
    public:
    Test(const std::string& data) { _data=data; std::cout<<"构造"<<std::endl; }
    Test(const Test& other) { _data=other._data; std::cout<<"拷贝"<<std::endl; }
    ~Test() { std::cout<<"析构"<<std::endl; }
};

int main(){
    {
        int a=10;
        double b=20;
        std::string c="hello world";
        Any any_a(a);
        Any any_b(b);
        Any any_c(c);
        int* aa=any_a.get<int>();
        double* bb=any_b.get<double>();
        std::string* cc=any_c.get<std::string>();

        std::cout<<*aa<<std::endl;
        std::cout<<*bb<<std::endl;
        std::cout<<*cc<<std::endl;
    }
    {
        Any a(10);
        Any b(a);
        Any c=b;
        int* aa=a.get<int>();
        int* bb=b.get<int>();
        int* cc=c.get<int>();
        std::cout<<*aa<<" "<<*bb<<" "<<*cc<<std::endl;
    }
    {
        Test t("test page");
        Any a(t);
        Any b(a);
        Any c=t;
    }
    return 0;
}